/*
 * Created by SharpDevelop.
 * User: MyWife
 * Date: 10/10/2010
 * Time: 10:18 AM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using popLib;
using popLib.ExtensionClass;
using System.Diagnostics;
using System.ComponentModel;
using System.IO;
using System.Collections;
using System.Data;
using System.Threading;

namespace MediafireDownloader
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	public partial class MainForm : Form
	{
		string data_file = FileLib.getFullPath("data.dat");
		DataSet ds = DataLib.initDataSet( "MDILinks[ #URL, File, FileSize, Link, Status, Password ]" );
		INISetting config;
		public MainForm()
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();
			
			
			dataGridView1.DataSource = ds.Tables["MDILinks"];
			LoadData();
			LoadConfig();
			
		}
		
		void LoadConfig(){
			if( config == null )
				config = new INISetting("config.ini");
			
			txt_idmpath.Text = config.GetValue("Setting", "IDM", @"C:\Program Files\Internet Download Manager\IDMan.exe");
			if( !File.Exists(txt_idmpath.Text) && FormLib.confirm("Current IDM Path is not valid. Do you want to browse for new file?") ){
				button3.PerformClick();
			}
			
			txt_storePath.Text = config.GetValue("Setting", "StorePath", "" );
			cbx_storePath.Checked = config.GetValue("Setting", "IsStorePath", "0" ) == "0" ? false : true;
			
			
			cbx_checkClipboard.Checked = config.GetValue("Setting", "IsAutoPasteClipboard", "0" ) == "0" ? false : true;
			
			cbx_delay.Checked = config.GetValue("Setting", "IsDelayDownload", "0" ) == "0" ? false : true;
			nud_delayminute.Value = NumberLib.getInt( config.GetValue("Setting", "DelayDownload_Minute", "12" ) );
			nud_delaycounter.Value = NumberLib.getInt( config.GetValue("Setting", "DelayDownload_Counter", "3" ) );
			
			cbx_fixname.Checked = config.GetValue("Setting", "IsFixName", "0" ) == "0" ? false : true;
		}
		void SaveConfig(){
			config.SetValue( "Setting", "IDM", txt_idmpath.Text );
			
			config.SetValue( "Setting", "IsStorePath", cbx_storePath.Checked ? "1" : "0" );
			config.SetValue( "Setting", "StorePath", txt_storePath.Text );
			
			
			
			config.SetValue( "Setting", "IsAutoPasteClipboard", cbx_checkClipboard.Checked ? "1" : "0" );
			
			config.SetValue( "Setting", "IsDelayDownload", cbx_delay.Checked ? "1" : "0" );
			config.SetValue( "Setting", "DelayDownload_Minute", nud_delayminute.Value.ToString() );
			config.SetValue( "Setting", "DelayDownload_Counter", nud_delaycounter.Value.ToString() );
			
			config.SetValue( "Setting", "IsFixName", cbx_fixname.Checked ? "1" : "0" );
			
			
			config.Save();
		}
		
		void LoadData(){
			if( !File.Exists(data_file) ) return;
			ds.ReadXml( data_file);
			foreach( DataRow row in ds.Tables["MDILinks"].Rows ){
				if( row["Status"].ToString().Equals("Get link") )
					row["Status"] = "Waiting";
			}
		}
		
		void SaveData(){
			ds.WriteXml(data_file);
		}
		
		
		void Button1Click(object sender, EventArgs e)
		{
			string content = Clipboard.GetText().ToLower().Replace("http://www.mediafire.com/download.php?", "http://www.mediafire.com/?").Replace("http://www.mediafire","|x$y|http://www.mediafire");
					
			ArrayList links = new ArrayList();
			if( content.Contains(" "))
			   links.AddRange( StringLib.getListGroupStringInside( content + " ", "|x$y|", " " ) );
			if( content.Contains("\n"))
				links.AddRange( StringLib.getListGroupStringInside( content + "\n", "|x$y|", "\n" ));			
			if( links.Count == 0 && content.StartsWith("|x$y|http://www.mediafire") )
				links.Add( content.Replace("|x$y|","") );
			
			if( Clipboard.ContainsData("HTML Format") ){
				content = Clipboard.GetData( "HTML Format" ).ToString().ToLower().Replace("http://www.mediafire.com/download.php?", "http://www.mediafire.com/?");
				links.AddRange( StringLib.getListGroupString( content , "\"http://www.mediafire", "\"" ));
			}
			
			string url = "";
			foreach( string link in links ){
				url = link.Replace("\r","").Replace("\n","").Replace("\t","").Replace("\"","");
				
				if( url.Trim().Length < 35 ) continue;
				if( url.Contains("http://www.mediafire.com/?sharekey") ) continue;
				if(ds.Tables["MDILinks"].Select("URL='"+url+"'").Length > 0) continue;
				
				ds.Tables["MDILinks"].Rows.Add( new object[]{ url, "", "", "", "Waiting", "" } );
			}
			
			SaveData();
		}
		
		Thread checkThread;		
		void Button2Click(object sender, EventArgs e)
		{
			if( button2.Text == "&Download" ){
				checkThread = new Thread(PerformDownloadFile);
				checkThread.IsBackground = true;
				checkThread.SetApartmentState(ApartmentState.STA);
				checkThread.Start();
				button2.Text = "&Stop";
				contextMenuStrip1.Enabled = button1.Enabled = button5.Enabled = cbx_checkClipboard.Enabled = false;
				dataGridView1.AllowUserToDeleteRows = false;
				checkClipboardTimer.Stop();
			}else{
				checkThread.Abort();
				button2.Text = "&Download";
				contextMenuStrip1.Enabled = button1.Enabled = button5.Enabled = cbx_checkClipboard.Enabled = true;				
				dataGridView1.AllowUserToDeleteRows = true;
				if( cbx_checkClipboard.Checked ) checkClipboardTimer.Start();
			}
		}
		

		void PerformDownloadFile(){			
			CycleDownload("Waiting");
			CycleDownload("Validated");
			CycleDownload("Request Timeout");
			CycleDownload("Request Timeout");			
			PerformClickDownload();
		}
		
		void PerformValidateFile(){			
			CycleValidate("Check link");
			CycleValidate("Waiting");
			CycleValidate("Request Timeout");
			PerformClickValidate();
		}
		
		
		
		public delegate void PerformClickDownloadDelegate();
		public void PerformClickDownload(){
			if( this.InvokeRequired ){
				this.Invoke( new PerformClickDownloadDelegate(PerformClickDownload) );
			}else{
				button2.PerformClick();
			}
		}
		
		public void PerformClickValidate(){
			if( this.InvokeRequired ){
				this.Invoke( new PerformClickDownloadDelegate(PerformClickValidate) );
			}else{
				button5.PerformClick();
			}
		}
		
		void CycleValidate( string status ){
			ChangeStatus( "Validating..." );
			
			foreach( DataRow row in ds.Tables["MDILinks"].Rows ){
				if( row[4].ToString().Equals(status) ){
					row[4] = "Check link";

					URLValidator form = new URLValidator(row[0].ToString());										
					form.ShowDialog();					
					
					if( form.Result == "OK" ){
						row[1] = form.Filename;
						row[2] = form.FileSize;
						row[4] = "Validated";
					}else
						row[4] = form.Result;
					
					
					SaveData();
				}
			}
		}
		
		
		void CycleDownload( string status ){
			int fileCounter = 0;
			int breakTimeDelay = 0;
			ChangeStatus( "Downloading..." );
			
			foreach( DataRow row in ds.Tables["MDILinks"].Rows ){
				if( row[4].ToString().Equals(status) ){
					row[4] = "Get link";

					URLCatcher form = new URLCatcher( row["URL"].ToString() , row["Password"].ToString());
					form.ShowDialog();					
					
					if( form.ResultURL.Success ){
						row[1] = Path.GetFileName(form.ResultURL.Message);
						row[3] = form.ResultURL.Message;
						addIDMQueue(form.ResultURL.Message);
						startIDMQueue();
						fileCounter++;
					}
					
					row[4] = form.ResultURL.Success ? "Queued" : form.ResultURL.Message;
					SaveData();
					
					if( cbx_delay.Checked && fileCounter >= Convert.ToInt16(nud_delaycounter.Value) ){
						//reset file counter
						fileCounter = 0;
						
						//get total minutes to wait
						breakTimeDelay = Convert.ToInt16(nud_delayminute.Value);
						
						//update status
						while(breakTimeDelay > 0){
							ChangeStatus( "Take a break ("+breakTimeDelay+" minutes)" );						
							Thread.Sleep(60000);
							breakTimeDelay--;
						}
						
						ChangeStatus( "Downloading..." );
					}
				}
			}
		}
		
		public delegate void ChangeStatusDelegate(string status);
		public void ChangeStatus(string status){
			if( this.InvokeRequired ){
				this.Invoke( new ChangeStatusDelegate(ChangeStatus), status );
			}else{
				lbl_status.Text = status;
			}
		}
		
		void addIDMQueue(string url){
			if( cbx_fixname.Checked ) url = url.Replace("+", " ");
			
			if( cbx_storePath.Checked ){				
				Process.Start( txt_idmpath.Text, string.Format( "/d \"{0}\" /a /p \"{1}\"", url, txt_storePath.Text) );
			}else
				Process.Start( txt_idmpath.Text, string.Format( "/d \"{0}\" /a", url ) );			
		}
		
		void startIDMQueue(){
			Process.Start( txt_idmpath.Text, "/s" );
		}
		
		void MainFormFormClosing(object sender, FormClosingEventArgs e)
		{
			SaveData();
			SaveConfig();
			
		}
		
		void ResetLinkToolStripMenuItemClick(object sender, EventArgs e)
		{
			foreach(DataGridViewRow row in dataGridView1.SelectedRows ){				
				row.Cells[3].Value = "";
				row.Cells[4].Value = "Waiting";
			}
			SaveData();
		}
		
		void PauseToolStripMenuItemClick(object sender, EventArgs e)
		{
			foreach(DataGridViewRow row in dataGridView1.SelectedRows ){
				row.Cells[4].Value = "Pause";
			}
			SaveData();
		}
		
		void DownloadToolStripMenuItemClick(object sender, EventArgs e)
		{
			foreach(DataGridViewRow row in dataGridView1.SelectedRows ){
				if( StringLib.isValid(row.Cells[3].Value.ToString() ) )
					addIDMQueue(row.Cells[3].Value.ToString());
			}
			startIDMQueue();
		}
		
		void CopyLinkToolStripMenuItemClick(object sender, EventArgs e)
		{
			string content = "";
			
			foreach(DataGridViewRow row in dataGridView1.SelectedRows ){
				content += row.Cells[0].Value.ToString()+"\r\n";					
			}
			
			try{ 
				Clipboard.SetText(content); 
			}catch{}
		}
		
		void OpenLinkToolStripMenuItemClick(object sender, EventArgs e)
		{
			foreach(DataGridViewRow row in dataGridView1.SelectedRows ){
				try{
					Process.Start(row.Cells[0].Value.ToString());
				}catch{}
			}
		}
		
		void PasteToolStripMenuItemClick(object sender, EventArgs e)
		{
			button1.PerformClick();
		}
		
		string lastClipboard = "";
		void CheckClipboardTimerTick(object sender, EventArgs e)
		{
			if( StringLib.isValid( Clipboard.GetText() ) && lastClipboard != Clipboard.GetText() ){
				lastClipboard = Clipboard.GetText();
				button1.PerformClick();
			}
		}
		
		void Cbx_checkClipboardCheckedChanged(object sender, EventArgs e)
		{
			if( cbx_checkClipboard.Checked ){
				checkClipboardTimer.Start();
			}else{
				checkClipboardTimer.Stop();
			}
		}
		
		
		
		void Button3Click(object sender, EventArgs e)
		{
			ReturnSet rs = FormLib.openFile( "Application files(*.exe)|*.exe|All files(*.*)|*.*", txt_idmpath.Text );
			if( rs.Success ){
				txt_idmpath.Text = rs.Result.ToString();
				SaveConfig();
			}
		}
		
		void MainFormSizeChanged(object sender, EventArgs e)
		{
			if( this.WindowState == FormWindowState.Minimized ){
				this.Hide();
			}
		}
		
		void NotifyIcon1Click(object sender, EventArgs e)
		{
			if( !this.Visible ){
				this.Show();
				if( this.WindowState == FormWindowState.Minimized )
					this.WindowState = FormWindowState.Normal;
			}else{
				this.Hide();
			}
		}
		
		void ViewTotal(){
			lbl_total.Text = string.Format("Select {0}/{1}", dataGridView1.SelectedRows.Count, dataGridView1.Rows.Count);
		}
		
		
		
		void DataGridView1SelectionChanged(object sender, EventArgs e)
		{
			ViewTotal();
		}
		
		void DataGridView1RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
		{
			ViewTotal();
		}
		
		void DataGridView1RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
		{
			ViewTotal();
		}
		
		void Button5Click(object sender, EventArgs e)
		{
			if( button5.Text == "&Validate" ){
				checkThread = new Thread(PerformValidateFile);
				checkThread.IsBackground = true;
				checkThread.SetApartmentState(ApartmentState.STA);
				checkThread.Start();
				button5.Text = "&Stop";
				contextMenuStrip1.Enabled = button1.Enabled = button2.Enabled = cbx_checkClipboard.Enabled = false;
				dataGridView1.AllowUserToDeleteRows = false;
				checkClipboardTimer.Stop();
			}else{
				checkThread.Abort();
				button5.Text = "&Validate";
				contextMenuStrip1.Enabled = button1.Enabled = button2.Enabled = cbx_checkClipboard.Enabled = true;				
				dataGridView1.AllowUserToDeleteRows = true;
				if( cbx_checkClipboard.Checked ) checkClipboardTimer.Start();
			}
		}
		
		void DataGridView1UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
		{
			e.Cancel = !FormLib.confirm("Are you sure you want to delete selected rows?");				
		}
		
		void Btn_storePathClick(object sender, EventArgs e)
		{
			ReturnSet rs = FormLib.folderBrowser();
			if( rs.Success ){
				txt_storePath.Text = (rs.Result.ToString()+" ").Replace("\\ ", "").Trim();
				SaveConfig();
			}
		}
		
		void Cbx_storePathCheckedChanged(object sender, EventArgs e)
		{
			btn_storePath.Enabled = txt_storePath.Enabled = cbx_storePath.Checked;
			nud_delaycounter.Enabled = nud_delayminute.Enabled = cbx_delay.Checked;
		}
	}
}
